/**
 * @Title: OrderServiceImpl
 * @Package cn.com.yiqi.wsc.service.order.impl
 * @Description: TODO
 * Copyright: Copyright (c) 2016
 * Company: 成都壹柒互动科技有限公司
 * @author 会员系统组-林威
 * @date 2017/2/15 10:39
 * @version V1.0
 */
package cn.com.yiqi.wsc.service.order.impl;

import cn.com.yiqi.wsc.Ro.*;
import cn.com.yiqi.wsc.common.Result;
import cn.com.yiqi.wsc.common.ResultUtil;
import cn.com.yiqi.wsc.config.weixin.WeixinpayConfig;
import cn.com.yiqi.wsc.dao.customer.CustomerMapper;
import cn.com.yiqi.wsc.dao.order.OrderMainMapper;
import cn.com.yiqi.wsc.dao.order.OrderPayDao;
import cn.com.yiqi.wsc.dao.order.OrderRefundDao;
import cn.com.yiqi.wsc.dao.order.OrderSubMapper;
import cn.com.yiqi.wsc.dao.org.OrgExtendDao;
import cn.com.yiqi.wsc.dao.org.criteria.AdminOrgCriteria;
import cn.com.yiqi.wsc.dao.shop.ItemMapper;
import cn.com.yiqi.wsc.entity.customer.Customer;
import cn.com.yiqi.wsc.entity.order.OrderMain;
import cn.com.yiqi.wsc.entity.order.OrderPay;
import cn.com.yiqi.wsc.entity.order.OrderRefund;
import cn.com.yiqi.wsc.entity.order.OrderSub;
import cn.com.yiqi.wsc.entity.org.OrgEntity;
import cn.com.yiqi.wsc.entity.org.OrgExtendEntity;
import cn.com.yiqi.wsc.entity.shop.Item;
import cn.com.yiqi.wsc.enumeration.IsDelete;
import cn.com.yiqi.wsc.ro.WeixinOrderRO;
import cn.com.yiqi.wsc.service.balance.BalanceService;
import cn.com.yiqi.wsc.service.balance.dataobject.BalanceRecordDO;
import cn.com.yiqi.wsc.service.balance.enumeration.BalanceType;
import cn.com.yiqi.wsc.service.customer.CustomerService;
import cn.com.yiqi.wsc.service.file.dataobject.QiniuConfig;
import cn.com.yiqi.wsc.service.item.ItemService;
import cn.com.yiqi.wsc.service.item.enumerate.ItemKindEnum;
import cn.com.yiqi.wsc.service.order.enumeration.OrderRefundStatus;
import cn.com.yiqi.wsc.service.order.enumeration.OrderStatus;
import cn.com.yiqi.wsc.service.order.enumeration.OrderSubStatus;
import cn.com.yiqi.wsc.service.order.enumeration.OrderType;
import cn.com.yiqi.wsc.service.org.impl.OrgServiceImpl;
import cn.com.yiqi.wsc.service.point.PointService;
import cn.com.yiqi.wsc.service.point.dataobject.PointOrderDO;
import cn.com.yiqi.wsc.service.sysparams.AppParamService;
import cn.com.yiqi.wsc.service.sysparams.SysParamsService;
import cn.com.yiqi.wsc.service.sysparams.dataobject.PointGetRuleDO;
import cn.com.yiqi.wsc.service.weixin.impl.WeixinPayImpl;
import cn.com.yiqi.wsc.util.OrderNoUtil;
import java.util.List;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.Date;

/**
 *
 *@ClassName: OrderServiceImpl
 * Description: TODO
 * @author 会员系统组-林威
 * @date 2017/2/15 10:39
 *
 */
@Service
public class OrderServiceImpl {

    @Autowired
    OrderMainMapper orderDao;

    @Autowired
    OrderSubMapper orderSubDao;

    @Autowired
    WeixinPayImpl weixinPay;

    @Autowired
    WeixinpayConfig weixinpayConfig;

    @Autowired
    ItemService itemService;

    @Autowired
    CustomerService customerService;

    @Autowired
    PointService pointService;

    @Autowired
    SysParamsService paramService;

    @Autowired
    BalanceService balanceService;

    @Autowired
    WeixinPayImpl weixinService;

    @Autowired
    OrderPayDao orderPayDao;

    @Autowired
    OrderRefundDao refundDao;

    @Autowired
    CustomerMapper customerDao;

    @Autowired
    ItemMapper itemDao;
    
    @Autowired
    QiniuConfig qiniuConfig;

    @Autowired
    OrgExtendDao orgExtendDao;

    @Autowired
    AppParamService appParamService;


    /**
     * 生成支付请求
     * */
    public Result precreate(int payChannel, String outTradeNo, String totalAmount, String subject, String body, String description, String ip)throws Exception {

        return null;
    }
    /**
     * 购买商品
     * */
    @Transactional
    public Result buyItem(OrderType type, Integer userId, Integer itemId,Integer count,Integer addressId,int orgId) {
        Result re = new Result();
        ItemDetailVO itemdetail = itemService.findItemDetail(itemId,userId);
        BigDecimal total = itemdetail.getNowPrice().multiply(new BigDecimal(""+count));
        OrderMain mainOrder = createMainOrder(type, total,userId,addressId);
        //子订单
        OrderMain order  = new OrderMain();
        order.setPid(mainOrder.getId());
        order.setAmount(total);
        if(itemdetail.getType() == 1){
            order.setType(Byte.parseByte(OrderType.buy_VIP.getValue()+""));
        }else if(itemdetail.getType() == 3){
            order.setType(Byte.parseByte(OrderType.point_exchange_order.getValue()+""));
        }else if(itemdetail.getType() == 2){
            order.setType(Byte.parseByte(OrderType.customer_order.getValue()+""));
        }
        order.setOrgId(orgId);
        order.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        order.setStatus(Byte.parseByte(OrderStatus.wait_to_pay.getValue()+""));
        order.setCreateTime(new Date());
        order.setCustomerId(userId);
        order.setCustomerAddressId(addressId);
        order.setOrderCode(OrderNoUtil.nextOrderId());
        orderDao.insertSelective(order);
        // 写ms_order_sub
            OrderSub sub = new OrderSub();
            sub.setOrderId(order.getId());
            sub.setAmount(total);
            sub.setCount(count);
            sub.setInsertTime(new Date());
            sub.setItemId(itemId);
            sub.setStatus(Byte.parseByte(OrderSubStatus.wait_to_pay.getValue()+""));
            orderSubDao.insertSelective(sub);
        //库存
        decreaseStok(itemId,count);
        re.putData("orderMain",mainOrder);
        return ResultUtil.success(re);

    }

    /**
     * 减少库存，增加销量
     * */
    private void decreaseStok(Integer itemId, Integer count) {
        Item item = itemService.findByid(itemId);
        int remain = item.getStock() - count;
        int soldCount = item.getSoldCount() == null?count :item.getSoldCount()+count;
        item.setStock(remain);
        item.setSoldCount(soldCount);
        itemDao.updateByPrimaryKeySelective(item);
    }

    /**
     * 购物车生成订单
     *
     */
    public Result createOrder(Integer userId, List<OrderDetailVo> orderDetails, BigDecimal totalAmout,Integer addressId){
        Result re = new Result();

        //减库存
        for (OrderDetailVo detailVo:orderDetails){
            for(CartVO vo:detailVo.getItems()){
                Item item = itemService.findByid(vo.getItemId());
                int remain = item.getStock()==null ?-1 :item.getStock() - vo.getCount() ;
                int soldCount = item.getSoldCount() == null?vo.getCount() :item.getSoldCount()+vo.getCount();
                if(remain < 0){
                    //手动回滚
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return ResultUtil.fail(re,"商品"+item.getName()+"库存不足！现存"+item.getStock()+"件!");
                }
                item.setStock(remain);
                item.setSoldCount(soldCount);
                itemDao.updateByPrimaryKeySelective(item);
            }
        }
        //生成总订单
        OrderMain mainOrder = createMainOrder(OrderType.customer_order, totalAmout,userId,addressId);
        //子订单生成
        for (OrderDetailVo vo:orderDetails){
            createDetailOrder(mainOrder.getId(),vo,userId,addressId);
        }
        re.putData("orderMain",mainOrder);
        return re;
    }

    /**
     * 生成订单列表
     * */
    private void createDetailOrder(Integer subOrderId,OrderDetailVo orderDetail, Integer userId,Integer addressId) {
        OrderMain order  = new OrderMain();
        order.setPid(subOrderId);
        order.setOrgId(orderDetail.getOrgId());
        order.setAmount(orderDetail.getTotalPrice());
        order.setType(Byte.parseByte(OrderType.customer_order.getValue()+""));
        order.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        order.setStatus(Byte.parseByte(OrderStatus.wait_to_pay.getValue()+""));
        order.setCreateTime(new Date());
        order.setCustomerId(userId);
        order.setCustomerAddressId(addressId);
        order.setOrderCode(OrderNoUtil.nextOrderId());
        orderDao.insertSelective(order);
        orderDetail.setOrderCode(order.getOrderCode());
        // 写ms_order_sub
        for(CartVO vo:orderDetail.getItems()){
            OrderSub sub = new OrderSub();
            sub.setOrderId(order.getId());
            sub.setAmount(vo.getPrice().multiply(new BigDecimal(""+vo.getCount())));
            sub.setCount(vo.getCount());
            sub.setInsertTime(new Date());
            sub.setItemId(vo.getItemId());
            sub.setStatus(Byte.parseByte(OrderSubStatus.wait_to_pay.getValue()+""));
            orderSubDao.insertSelective(sub);
        }

    }


    /**
     * 生成总订单
     * */

    private OrderMain createMainOrder(OrderType type, BigDecimal amount,Integer userId,Integer addressId){
        // 生成总订单
        OrderMain order = new OrderMain();
        //总订单pid为0
        order.setPid(0);
        order.setOrderCode(OrderNoUtil.nextOrderId());
        order.setCustomerId(userId);
        order.setAmount(amount);
        order.setCustomerAddressId(addressId);
        order.setType(Byte.parseByte(type.getValue()+""));
        order.setCreateTime(new Date());
        order.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        order.setStatus(Byte.parseByte(OrderStatus.wait_to_pay.getValue()+""));
        orderDao.insertSelective(order);
        return order;
    }

    /**
     * 查询子订单详情
     * */
    public List<OrderDetailVo> findOrderDetails(Integer userId,Integer orderState){
        return orderDao.findOrderDetailSons(userId,orderState);

    }

    /**
     * 订单查询
     * */
    public List<MainOrderVo> findOrderDetailByCustomerId(Integer userId, Integer orderState) {
        return  orderDao.findOrderDetails(userId,orderState);
    }

    /**
     * 查询所有订单
     * */
    public PageInfo<MainOrderVo> findOrderDetailByCustomerIdPage(Integer userId, Integer currentPage, Integer pageSize) {
        PageHelper.startPage(currentPage,pageSize);
        return new PageInfo<>(orderDao.findOrderDetails(userId,null));
    }

    /**
     * 查询订单详情
     * */
    public OrderDetailVo findOrderDetailById(Integer id) {
        return orderDao.findOrderDetailByOrderId(id);
    }

    /**
     * 微信支付参数
     * */
    public Result preCreate(Integer orderId,BigDecimal amount,String ip) {

        Result re = new Result();
        OrderMain order = orderDao.selectByPrimaryKey(orderId);

        if(order == null || order.getPid() != 0 ){
            //只能支付主订单
            return ResultUtil.fail(re,"param error");
        }else if(order.getStatus().intValue() != OrderStatus.wait_to_pay.getValue()){
            return ResultUtil.fail(re,"订单不可支付");
        }
        String openid = customerDao.findByOpenId(null,order.getCustomerId()).getLoginAccount();

        WeixinOrderRO ro = new WeixinOrderRO();
        ro.setAppid(weixinpayConfig.getAppid());
        ro.setMch_id(weixinpayConfig.getMch_id());
        ro.setNonce_str(RandomStringUtils.randomAlphanumeric(20));
        ro.setAttach(order.getOrderCode());
        ro.setOut_trade_no(order.getOrderCode());
        ro.setTotal_fee((amount.multiply(new BigDecimal(""+100))).intValue());
        ro.setBody(order.getOrderCode());
        ro.setSpbill_create_ip(ip);
        ro.setNotify_url(weixinpayConfig.getNotify_url());
        ro.setTrade_type(weixinpayConfig.getTrade_type());
        ro.setOpenid(openid);
        return weixinPay.precreate(ro);
    }


    /**
     * 订单能抵扣多少积分
     * */
    public Integer sumCanPoint(Integer orderId) {
        return orderDao.sumCanPoint(orderId);
    }

    @Transactional
    public Result isOrderCanPay(Integer userId, Integer orderId) {

        Result re = new Result();
        OrderMain orderMain = orderDao.findOrder(userId, orderId);
        if(null == orderMain ){
            return ResultUtil.fail(re,"订单不存在或不可支付！");
        }
        if(Integer.parseInt(orderMain.getStatus()+"") == OrderStatus.wait_to_pay.getValue() ){
            //  调用微信接口查询订单是否支付
            Boolean hasPaid = weixinService.searchOrder(orderMain.getOrderCode());
            if(!hasPaid){
                re.setReturnValue(orderMain);
                return ResultUtil.success(re);
            }else {
                // 修改订单状态为已支付并扣除冻结的积分
                orderMain.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
                orderMain.setPayTime(new Date());
                orderDao.updateByPrimaryKeySelective(orderMain);
                //判断是否有余额 或者 积分支付 有则增加使用记录(支付未完成时减了余额但没有增加记录)
                OrderPay orderPay = orderPayDao.getOrderPayDetailByOrderId(orderMain.getId());
                if(null != orderPay){
                    //如果有积分支付
                    if(null != orderPay.getCostPoint()){
                        PointOrderDO pdo = new PointOrderDO();
                        pdo.setHasDeal(true);
                        pdo.setPoint(orderPay.getCostPoint());
                        pdo.setCustomerId(Long.parseLong(orderMain.getCustomerId()+""));
                        orderPay.setPointRecordId(pointService.dealUse(pdo).getReturnValue().intValue());
                    }
                    if(null != orderPay.getBalancePay()){
                        BalanceRecordDO bdo = new BalanceRecordDO();
                        bdo.setHasDeal(true);
                        bdo.setCustomerId(Long.parseLong(orderMain.getCustomerId()+""));
                        bdo.setAmount(orderPay.getBalancePay());
                        bdo.setType(BalanceType.buy);
                        bdo.setBizId(orderMain.getId());
                        bdo.setDesc("余额购买商品("+orderMain.getOrderCode()+")");
                        orderPay.setBalanceRecordId(balanceService.CostBalance(bdo));
                    }
                    orderPayDao.update(orderPay);
                }
                return ResultUtil.fail(re,"订单已支付！");
            }
        }
        return ResultUtil.fail(re,"订单不可支付！");
    }
    /**
     * 计算最终支付金额
     * */
    @Transactional
    public Result<BigDecimal> calWxAmout(Integer userId, Integer orderId, BigDecimal orderbalance, Integer orderPoint) {
        Result<BigDecimal> re = new Result();
        OrderPay hasPaid = orderPayDao.getOrderPayDetailByOrderId(orderId);
        if( hasPaid != null ){
            return ResultUtil.fail(re,"请不要重复提交");
        }
        Customer user = customerService.selectById(userId);
        OrderMain order = orderDao.findOrder(userId,orderId);
        if(null == order || order.getStatus() != Byte.parseByte(OrderStatus.wait_to_pay.getValue()+"")){
            return ResultUtil.fail(re,"订单不可支付");
        }
        OrderPay orderPay = new OrderPay();
        BigDecimal orderPayWxMax = order.getAmount();
        //判断积分
        BigDecimal pointPay = BigDecimal.ZERO;
        if(null != orderPoint){
            Integer point = user.getPoint()==null ?0:user.getPoint();
            if(orderPoint > point){
                return ResultUtil.fail(re,"积分不足!");
            }
            Integer canPoint = sumCanPoint(orderId);
            if(null == canPoint || canPoint < orderPoint){
                return ResultUtil.fail(re,"积分大于订单可使用积分!");
            }
            pointPay =  new BigDecimal(""+paramService.getPointPara().getPointScale()).multiply(new BigDecimal(""+orderPoint));
            orderPayWxMax = order.getAmount().subtract(pointPay);
        }
        //判断余额
        if(null != orderbalance ){
            if(user.getBalance().compareTo(orderbalance) < 0 || orderbalance.compareTo(orderPayWxMax) > 0){
                return ResultUtil.fail(re,"余额不足或大于订单总额！");
            }
            orderPayWxMax = orderPayWxMax.subtract(orderbalance);
        }
        //如果完全是余额+积分支付方式
        Long pointBizId = null;
        Integer balaceBizId = null;
        if(orderPayWxMax.compareTo(BigDecimal.ZERO) == 0){
            //订单状态改为代发货
            if(order.getType() == OrderType.buy_VIP.getValue()){
                order.setStatus(Byte.parseByte(OrderStatus.confirmed.getValue()+""));
                //给用户续vip
                Item item = itemService.findItemByVipOrder(order.getId());
                customerService.addVipTime(order.getCustomerId(),item);
            }else {
                order.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
            }

            order.setPayTime(new Date());
            orderDao.updateByPrimaryKeySelective(order);

            //子订单状态修改
            List<OrderMain> orderSons = orderDao.findOrdersByPid(order.getId());
            for (OrderMain orderson:orderSons){
                orderson.setStatus(order.getStatus());
                orderDao.updateByPrimaryKeySelective(orderson);
            }

            //订单详情状态改为已支付
            orderSubDao.changeStatus(order.getId(),OrderSubStatus.has_payed.getValue());

            //插入积分余额使用记录
            if(null != orderPoint){
                PointOrderDO pdo = new PointOrderDO();
                pdo.setBizDesc("交易使用");
                pdo.setPoint(orderPoint);
                pdo.setCustomerId(Long.parseLong(userId+""));
                pointBizId = pointService.dealUse(pdo).getReturnValue();
            }
            if(null != orderbalance){
                BalanceRecordDO bdo = new BalanceRecordDO();
                bdo.setCustomerId(Long.parseLong(userId+""));
                bdo.setBizId(orderId);
                bdo.setAmount(orderbalance);
                bdo.setType(BalanceType.buy);
                bdo.setDesc("余额购买商品("+order.getOrderCode()+")");
                balaceBizId = balanceService.CostBalance(bdo);
            }
            orderPay.setPayTime(new Date());
        }else {
            //扣除用户积分(不新增积分使用记录)

            if(null != orderPoint){
                user.setPoint(user.getPoint() - orderPoint);
            }
            if(null != orderbalance){
                user.setBalance(user.getBalance().subtract(orderbalance));
            }
            if(null != orderPoint || null != orderbalance){
                customerService.updateCustomer(user);
            }
        }
        //支付记录

        orderPay.setPointRecordId(pointBizId==null?null:pointBizId.intValue());
        orderPay.setPointPay(orderPoint==null?null:pointPay);
        orderPay.setBalanceRecordId(balaceBizId);
        orderPay.setPayMode(1);
        orderPay.setOrderId(orderId);
        orderPay.setAmount(orderPayWxMax);
        orderPay.setBalancePay(orderbalance);
        orderPay.setCostPoint(orderPoint);
        orderPayDao.insert(orderPay);
        re.setReturnValue(orderPayWxMax);
        return ResultUtil.success(re);
    }

    /**
     * 微信回调订单支付成功
     * */
    public void orderPaySuccess(String outTradeNo, String tradeNo, Date paidDate,String openId) {
        //订单状态
        OrderMain order = orderDao.selectByorderCode(outTradeNo);
        if(order.getType() == OrderType.buy_VIP.getValue()){
            order.setStatus(Byte.parseByte(OrderStatus.confirmed.getValue()+""));
            //给用户续vip
            Item item = itemService.findItemByVipOrder(order.getId());
            customerService.addVipTime(order.getCustomerId(),item);
        }else {
            order.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
        }
        order.setPayTime(paidDate);
        orderDao.updateByPrimaryKeySelective(order);

        //支付记录
        OrderPay orderPay = orderPayDao.getOrderPayDetailByOrderId(order.getId());
        orderPay.setExternalPayNo(tradeNo);
        orderPay.setExternalUid(openId);
        orderPay.setPayTime(paidDate);
        //如果有积分支付
        if(null != orderPay.getCostPoint()){
            PointOrderDO pdo = new PointOrderDO();
            pdo.setHasDeal(true);
            pdo.setPoint(orderPay.getCostPoint());
            pdo.setCustomerId(Long.parseLong(order.getCustomerId()+""));
            orderPay.setPointRecordId(pointService.dealUse(pdo).getReturnValue().intValue());
        }
        if(null != orderPay.getBalancePay()){
            BalanceRecordDO bdo = new BalanceRecordDO();
            bdo.setHasDeal(true);
            bdo.setCustomerId(Long.parseLong(order.getCustomerId()+""));
            bdo.setAmount(orderPay.getBalancePay());
            bdo.setType(BalanceType.buy);
            bdo.setBizId(order.getId());
            bdo.setDesc("余额购买商品("+order.getOrderCode()+")");
            orderPay.setBalanceRecordId(balanceService.CostBalance(bdo));
        }
        orderPayDao.update(orderPay);
        //子订单状态修改
        List<OrderMain> orderSons = orderDao.findOrdersByPid(order.getId());
        for (OrderMain orderson:orderSons){
            orderson.setStatus(order.getStatus());
            orderDao.updateByPrimaryKeySelective(orderson);
        }
        //订单详情状态改为已支付
        orderSubDao.changeStatus(order.getId(),OrderSubStatus.has_payed.getValue());

    }

    /**商品退款*/
    public Result orderRefund(Integer userId, Integer orderSubId,String reson) {
        Result re = new Result();
        OrderSub orderSub = orderSubDao.selectByUserIdAndId(userId,orderSubId);
        if(null == orderSub){
            return ResultUtil.fail(re,"您没有购买过此商品");
        }
        OrderRefund orderrefund = refundDao.findByOrderSubId(orderSubId);
        if(orderrefund != null ){
            return ResultUtil.fail(re,"已申请过退款");
        }
        //子订单
        OrderMain order = orderDao.selectByPrimaryKey(orderSub.getOrderId());
        order = orderDao.selectByPrimaryKey(order.getPid());
        Integer orderState = Integer.parseInt(order.getStatus()+"");
        if(order.getType() != OrderType.customer_order.getValue() ||  (orderState != OrderStatus.wait_to_get.getValue() && orderState != OrderStatus.wait_to_send.getValue())){
            return ResultUtil.fail(re,"订单不可退款！");
        }

        OrderPay orderpay = orderPayDao.getOrderPayDetailByOrderId(order.getId());
        Integer itemPoint = itemService.findByid(orderSub.getItemId()).getUsePoint();
        if(orderpay.getPointRecordId() != null && itemPoint != null && itemPoint > 0){
            return ResultUtil.fail(re,"积分抵扣的订单不能退货！");
        }

        orderSub.setStatus(Byte.parseByte(OrderSubStatus.has_back_goods.getValue()+""));
        orderSubDao.updateByPrimaryKeySelective(orderSub);
        //申请退货
        orderrefund = new OrderRefund();
        orderrefund.setCode(OrderNoUtil.nextOrderId());
        orderrefund.setCustomerId(userId);
        orderrefund.setOrderSubId(orderSubId);
        orderrefund.setDisputeType(1);//纠纷类型 1_售中退款，2_售后退款，默认为售中退款
        orderrefund.setRefundType(1);//退款类型 1退款 2退货 3退货退款
        orderrefund.setIsReceived(0);//退货是否已收到货 0否 1是
        orderrefund.setRefundAmount(orderSub.getAmount());
        orderrefund.setStatus(OrderRefundStatus.org_check.getValue());
        orderrefund.setRefundReason(reson);
        orderrefund.setApplyTime(new Date());
        refundDao.insert(orderrefund);
        return ResultUtil.success(re);
    }

    /**
     * 订单支付前返回上次支付时候冻结的余额和积分
     * */
    public void returnFrizee(Integer userId,Integer orderId) {
        Customer user = customerService.selectById(userId);
        OrderPay orderpay = orderPayDao.getOrderPayDetailByOrderId(orderId);
        if(null != orderpay){
            if(null != orderpay.getCostPoint()){
               user.setPoint(user.getPoint()+orderpay.getCostPoint());
            }
            if(null != orderpay.getBalancePay()){
                user.setBalance(user.getBalance().add(orderpay.getBalancePay()));
            }
            if(null != orderpay.getCostPoint() || null != orderpay.getBalancePay() ){
                customerService.updateCustomer(user);
            }
            orderPayDao.delete(orderpay);
        }

    }

    /**退款记录*/
    public List<RefundItemVO> refundList(Integer userId,Integer id) {
        return refundDao.selectRefundItemVOList(userId,id,qiniuConfig.getURL()+"/");
    }

    /**
     * 积分兑换订单
     * */
    @Transactional
    public void createPointOrder(Integer userId, Integer itemId,Integer addressId) {
        Item item = itemService.findByid(itemId);
        //用户积分记录
        PointOrderDO pdo = new PointOrderDO();
        pdo.setCustomerId(Long.parseLong(userId+""));
        pdo.setPoint(item.getPointPrice());
        pdo.setBizDesc("积分购买商品");
        Result<Long> re = pointService.dealUse(pdo);
        if(!ResultUtil.isSuccess(re)){
            return;
        }
        Long id = re.getReturnValue();
        // 生成总订单
        OrderMain order = new OrderMain();
        //总订单pid为0
        order.setPid(0);
        order.setCustomerAddressId(addressId);
        order.setOrderCode(OrderNoUtil.nextOrderId());
        order.setCustomerId(userId);
        order.setAmount(new BigDecimal(""+item.getPointPrice()));
        order.setCustomerAddressId(addressId);
        order.setType(Byte.parseByte(OrderType.point_exchange_order.getValue()+""));
        order.setCreateTime(new Date());
        order.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        order.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
        order.setPayTime(new Date());
        orderDao.insertSelective(order);

        //子订单
        OrderMain orderSub  = new OrderMain();
        orderSub.setPayTime(new Date());
        orderSub.setOrgId(item.getOrgId());
        orderSub.setPid(order.getId());
        orderSub.setAmount(order.getAmount());
        orderSub.setType(Byte.parseByte(OrderType.point_exchange_order.getValue()+""));
        orderSub.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        orderSub.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
        orderSub.setCreateTime(new Date());
        orderSub.setCustomerId(userId);
        orderSub.setCustomerAddressId(addressId);
        orderSub.setOrderCode(OrderNoUtil.nextOrderId());
        orderDao.insertSelective(orderSub);
        // 写ms_order_sub
        OrderSub sub = new OrderSub();
        sub.setOrderId(orderSub.getId());
        sub.setAmount(orderSub.getAmount());
        sub.setCount(1);
        sub.setInsertTime(new Date());
        sub.setItemId(itemId);
        sub.setStatus(Byte.parseByte(OrderSubStatus.has_payed.getValue()+""));
        orderSubDao.insertSelective(sub);
        //orderPay
        OrderPay orderPay = new OrderPay();
        orderPay.setCostPoint(item.getPointPrice());
        orderPay.setBalanceRecordId(id.intValue());
        orderPay.setOrderId(order.getId());
        orderPay.setPayTime(new Date());
        orderPayDao.insert(orderPay);
        //库存 -1销量 +1
        int remain = item.getStock() - 1;
        int soldCount = item.getSoldCount() == null?1 :item.getSoldCount()+1;
        item.setSoldCount(soldCount);
        item.setStock(remain);
        itemDao.updateByPrimaryKeySelective(item);

    }

    /**
     * 积分购买vip
     * */
    @Transactional
    public void createVipOrder(Integer userId, Integer itemId,Integer orgId) {
        Item item = itemService.findByid(itemId);
        //用户积分记录
        PointOrderDO pdo = new PointOrderDO();
        pdo.setCustomerId(Long.parseLong(userId+""));
        pdo.setPoint(item.getPointPrice());
        pdo.setBizDesc("购买VIP");
        Result<Long> re = pointService.dealUse(pdo);
        if(!ResultUtil.isSuccess(re)){
            return;
        }
        Long id = re.getReturnValue();
        // 生成总订单
        OrderMain order = new OrderMain();
        //总订单pid为0
        order.setPid(0);
        order.setOrderCode(OrderNoUtil.nextOrderId());
        order.setCustomerId(userId);
        order.setAmount(new BigDecimal(""+item.getPointPrice()));
        order.setCustomerAddressId(null);
        order.setType(Byte.parseByte(OrderType.buy_VIP.getValue()+""));
        order.setCreateTime(new Date());
        order.setPayTime(new Date());
        order.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        order.setStatus(Byte.parseByte(OrderStatus.confirmed.getValue()+""));
        orderDao.insertSelective(order);

        //子订单
        OrderMain orderSub  = new OrderMain();
        orderSub.setOrgId(item.getOrgId());
        orderSub.setPid(order.getId());
        orderSub.setPayTime(new Date());
        orderSub.setAmount(order.getAmount());
        orderSub.setType(Byte.parseByte(OrderType.buy_VIP.getValue()+""));
        orderSub.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        orderSub.setStatus(Byte.parseByte(OrderStatus.confirmed.getValue()+""));
        orderSub.setCreateTime(new Date());
        orderSub.setCustomerId(userId);
        orderSub.setCustomerAddressId(null);
        orderSub.setOrderCode(OrderNoUtil.nextOrderId());
        orderDao.insertSelective(orderSub);
        // 写ms_order_sub
            OrderSub sub = new OrderSub();
            sub.setOrderId(orderSub.getId());
            sub.setAmount(orderSub.getAmount());
            sub.setCount(1);
            sub.setInsertTime(new Date());
            sub.setItemId(itemId);
            sub.setStatus(Byte.parseByte(OrderSubStatus.has_payed.getValue()+""));
            orderSubDao.insertSelective(sub);

        //orderPay
        OrderPay orderPay = new OrderPay();
        orderPay.setCostPoint(item.getPointPrice());
        orderPay.setPointRecordId(id.intValue());
        orderPay.setOrderId(order.getId());
        orderPay.setPayTime(new Date());
        orderPayDao.insert(orderPay);

        //库存 -1销量 +1
        int remain = item.getStock() - 1;
        int soldCount = item.getSoldCount() == null?1 :item.getSoldCount()+1;
        item.setSoldCount(soldCount);
        item.setStock(remain);
        itemDao.updateByPrimaryKeySelective(item);
        //增加用户vip时长
        customerService.addVipTime(userId,item);

    }
    /**
     * 中奖订单
     * */
    @Transactional
    public Result createLotteryOrder(Item item, Integer userId, Integer addressId) {
        Result re = new Result();
        OrderMain order = new OrderMain();
        //子订单
        OrderMain orderSub  = new OrderMain();
        //如果是vip商品则直接送vip
        if(item.getKind() == ItemKindEnum.vip.getValue()){
            //增加用户vip时长
            customerService.addVipTime(userId,item);
            order.setStatus(Byte.parseByte(OrderStatus.confirmed.getValue()+""));
            orderSub.setStatus(Byte.parseByte(OrderStatus.confirmed.getValue()+""));
        }else {
            order.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
            orderSub.setStatus(Byte.parseByte(OrderStatus.wait_to_send.getValue()+""));
        }

        //总订单pid为0
        order.setAmount(BigDecimal.ZERO);
        order.setPid(0);
        order.setOrderCode(OrderNoUtil.nextOrderId());
        order.setCustomerId(userId);
        order.setCustomerAddressId(addressId);
        order.setType(Byte.parseByte(OrderType.lottery_order.getValue()+""));
        order.setCreateTime(new Date());
        order.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        order.setPayTime(new Date());
        orderDao.insertSelective(order);

        orderSub.setOrgId(item.getOrgId());
        orderSub.setPid(order.getId());
        orderSub.setPayTime(new Date());
        orderSub.setAmount(order.getAmount());
        orderSub.setType(Byte.parseByte(OrderType.lottery_order.getValue()+""));
        orderSub.setIsDelete(Byte.parseByte(IsDelete.no.getValue()+""));
        orderSub.setCreateTime(new Date());
        orderSub.setCustomerId(userId);
        orderSub.setCustomerAddressId(null);
        orderSub.setOrderCode(OrderNoUtil.nextOrderId());
        orderSub.setCustomerAddressId(addressId);
        orderDao.insertSelective(orderSub);
        // 写ms_order_sub
        OrderSub sub = new OrderSub();
        sub.setOrderId(orderSub.getId());
        sub.setAmount(orderSub.getAmount());
        sub.setCount(1);
        sub.setInsertTime(new Date());
        sub.setItemId(item.getId());
        sub.setStatus(Byte.parseByte(OrderSubStatus.has_payed.getValue()+""));
        orderSubDao.insertSelective(sub);

        //orderPay
        OrderPay orderPay = new OrderPay();
        orderPay.setOrderId(order.getId());
        orderPay.setPayTime(new Date());
        orderPayDao.insert(orderPay);

        //库存 -1销量 +1
        int remain = item.getStock() - 1;
        int soldCount = item.getSoldCount() == null?1 :item.getSoldCount()+1;
        item.setSoldCount(soldCount);
        item.setStock(remain);
        itemDao.updateByPrimaryKeySelective(item);

        return ResultUtil.success(re);
    }

    public CartVO findOrderSubDetail(Integer id) {
        return orderSubDao.findOrderSub(id,qiniuConfig.getURL()+"/");
    }

    /**
     * 订单超过30分钟取消
     * */
    @Transactional
    public void calcelOrderTask() {
        List<OrderMain> orders = orderDao.findOrderWaitToPay(30);
        for (OrderMain order:orders){
            calcelOrder(order);
        }
    }

    /**
     * 取消订单
     * */
    private void calcelOrder(OrderMain order) {
        //返还扣除的积分和余额
        returnFrizee(order.getCustomerId(),order.getId());
        orderDao.updateOrderAndOrderSonState(OrderStatus.cancel.getValue(),order.getId());
        //商品库存和销量复原
        setBackStockByOrderMainId(order.getId());
    }

    /**
     * 根据取消订单的订单id复原商品的销量和库存
     * */
    private void setBackStockByOrderMainId(Integer orderId){
        List<CartVO> vos =  orderDao.findVartVosByOrderId(orderId);
        for (CartVO ca:vos){
            Item item = itemDao.selectByPrimaryKey(ca.getItemId());
            int remain = item.getStock()==null?ca.getCount():item.getStock()+ca.getCount();
            int soldCout = item.getSoldCount()==null?0:item.getSoldCount()-ca.getCount()<0?0:item.getSoldCount()-ca.getCount();
            item.setStock(remain);
            item.setSoldCount(soldCout);
            itemDao.updateByPrimaryKeySelective(item);
        }
    }

    /**
     * 定时任务确认收货
     * */
    public void comfirmOrderTask(Integer days){
        List<OrderMain> orders = orderDao.findOrderToComfirm(days*24);
        for (OrderMain order:orders){
            comfirm(order);
        }
    }


    /**
     * 确认收货订单
     * */

    @Transactional
    public Result<Customer> comfirmOrder(Integer userId, Integer orderId) {
        Result re = new Result();
        OrderMain order = orderDao.findOrder(userId,orderId);
        if(order.getPid() == 0 || Integer.parseInt(order.getStatus()+"") != OrderStatus.wait_to_get.getValue()){
            return ResultUtil.fail(re,"订单不能确认收货！");
        }
        comfirm(order);
        return ResultUtil.success(re);
    }

    /**
     * 确认收货
     * */
    @Transactional
    private Result comfirm(OrderMain order){
        Result re  =  new Result();
        Byte comfirmStatus = Byte.parseByte(OrderStatus.confirmed.getValue()+"");
        order.setStatus(comfirmStatus);
        order.setConfirmedTime(new Date());
        orderDao.updateByPrimaryKeySelective(order);
        //增加商家销售金额
        dealOrgExtend(order.getId());
        //  分销
        customerService.spread(order);

        //是否主订单所有子订单都确认收货
        List<OrderMain> orders = orderDao.findOrdersByPid(order.getPid());
        for (OrderMain orderSon:orders){
        	//已确认/已取消
            if(orderSon.getStatus() != comfirmStatus && orderSon.getStatus() != Byte.parseByte(OrderStatus.cancel.getValue()+"") ){
                return ResultUtil.success(re);
            }
        }
        //改大订单为已确认
        OrderMain orderFather = orderDao.selectByPrimaryKey(order.getPid());
        orderFather.setStatus(comfirmStatus);
        orderDao.updateByPrimaryKeySelective(orderFather);
        //增加用户消费金额 2017-4-10 消费送积分
        OrderPay orderPay = orderPayDao.getOrderPayDetailByOrderId(orderFather.getId());
        if(null != orderPay){
            Customer customer = customerService.selectById(orderFather.getCustomerId());
            BigDecimal dealAmount = customer.getDealAmount() == null ? BigDecimal.ZERO:customer.getDealAmount();
            BigDecimal payAmount = orderPay.getAmount() == null ? BigDecimal.ZERO : orderPay.getAmount();
            BigDecimal balanceAmount = orderPay.getBalancePay() == null ? BigDecimal.ZERO : orderPay.getBalancePay();
            Integer dealTime = customer.getDealTimes() == null ? 0 : customer.getDealTimes();
            customer.setDealAmount(dealAmount.add(payAmount).add(balanceAmount));
            customer.setDealTimes(dealTime + 1);
            customerDao.updateByPrimaryKeySelective(customer);
            //消费送积分
            grandPointByOrderId(orderFather.getId());
        }

        return ResultUtil.success(re);
    }

    /**
     * 已完成的订单给用户返还积分
     * */
    public void grandPointByOrderId(Integer orderId) {
        PointGetRuleDO ruleDo = appParamService.getPointGetRule();
        if(ruleDo.isSendPoint()){
            OrderMain order = orderDao.selectByPrimaryKey(orderId);
            OrderPay orderPay = orderPayDao.getOrderPayDetailByOrderId(orderId);

            if(null != order && null != orderPay){
                BigDecimal totalPay = null;
                BigDecimal balacePay = orderPay.getBalancePay() == null ? BigDecimal.ZERO :orderPay.getBalancePay();
                BigDecimal wxPay = orderPay.getAmount() == null ? BigDecimal.ZERO :orderPay.getAmount();
                totalPay = balacePay.add(wxPay);
                //有积分抵扣 则不会存在退款情况 只需计算支付金额
                if(orderPay.getPointPay() != null && orderPay.getPointPay().compareTo(BigDecimal.ZERO) > 0){
                    BigDecimal refundTotal = refundDao.sumRefundByOrderId(orderId);
                    totalPay = totalPay.subtract(refundTotal);
                }
                Integer point = 0;
                Customer customer = customerService.selectById(order.getCustomerId());
                if(totalPay.compareTo(BigDecimal.ZERO) > 0){
                    int vip = customer.getVip() == null ? 0 : customer.getVip();
                    point = vip == 1 ? totalPay.multiply(new BigDecimal(ruleDo.getVipPointRate()+"")).intValue() : totalPay.multiply(new BigDecimal(ruleDo.getPointRate()+"")).intValue();
                }
                if(point > 0){
                    PointOrderDO pdo = new PointOrderDO();
                    pdo.setBizDesc("消费送积分");
                    pdo.setCustomerId(Long.parseLong(customer.getId()+""));
                    pdo.setPoint(point);
                    pointService.grantPoint(pdo);
                }
            }
        }
    }

    /**
     * 根据订单id更新商家销量和销售额
     * */
    private void dealOrgExtend(Integer id) {
        OrderDetailVo vo = findOrderDetailById(id);
        if(null != vo){
            for (CartVO cvo:vo.getItems()){
                if(null != cvo.getOrgId()){
                    AdminOrgCriteria cretira = new AdminOrgCriteria();
                    cretira.setOrgId(cvo.getOrgId());
                    OrgExtendEntity extendEntity = orgExtendDao.getDetailExtendByOrgId(cretira);
                    BigDecimal saleAmount = extendEntity.getSaleAmount() == null ? BigDecimal.ZERO :extendEntity.getSaleAmount();
                    BigDecimal addAmount = cvo.getPrice() == null ? BigDecimal.ZERO : cvo.getPrice().multiply(new BigDecimal(cvo.getCount()+""));
                    extendEntity.setSaleAmount(saleAmount.add(addAmount));
                    int saleCount = extendEntity.getSaleCount() == null ? 0 : extendEntity.getSaleCount();
                    extendEntity.setSaleCount(saleCount + cvo.getCount());
                    orgExtendDao.update(extendEntity);
                }
            }
        }
    }
}
